package myreflect4;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * Method类中用于创建对象的方法
 *   Object invoke(Object obj,Object...args):运行方法
 *   参数一：用obj对象调用该方法
 *   参数二：调用方法的传递参数(如果没有就不写)
 *   返回值：方法的返回值(如果没有就不写)
 *
 *  获取方法的修饰符
 *  获取方法的名字
 *  获取方法的形参
 *  获取方法的返回值
 *  获取方法的抛出的异常
 */
public class MyReflectDemo {

    /**
     * 1.获取class字节码文件对象
     * Class.forName("src.main.java.myreflect4.Student.java")
     */
    Class<?> clazz = Class.forName("myreflect4.Student");

    public MyReflectDemo() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        System.out.println("MyReflectDemo");

        /**
         * 2.获取里面所有的方法对象(包含父类中所有的公共方法)
         */
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        /**
         * 3.获取里面所有的方法对象(不不能获取父类的,但是可以获取本类中私有的)
         */

        Method[] methods1 = clazz.getDeclaredMethods();
        System.out.println(methods1);

        //获取指定的单元方法
        Method eat = clazz.getDeclaredMethod("eat", String.class, int.class);
        System.out.println(eat);

        //获取方法的名字
        String name = eat.getName();
        System.out.println(name);

        //获取方法的形参
        Parameter[] parameters = eat.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

       // 获取方法的抛出的异常
        Class[] exceptionTypes = eat.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        /*Student s = new Student();
        eat.setAccessible(true);//因为eat方法是私有的,所以需要设置暂时取消访问权限
        eat.invoke(s,"炸鸡");*/

        //获取单个的成员变量
       Field na= clazz.getDeclaredField("name");
        System.out.println(na);

        //获取权限修饰符
        int modifiers = na.getModifiers();
        System.out.println(modifiers);

        //获取成员变量的名字
        String n = na.getName();
        System.out.println(n);

        //获取成员变量的数据类型
        Class<?> type = na.getType();
        System.out.println(type);

       //获取成员变量记录的值
        Student s = new Student("wangwu", 22, "男");
        na.setAccessible(true);
        Object value = na.get(s);
        System.out.println(value);

        //修改对象里面记录的值
        na.set(s,"zhangsan");
        System.out.println(s);


    }


}
